package com.hliushi.netty.protocol;

import com.alibaba.fastjson.JSONObject;
import com.hliushi.netty.message.Message;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageCodec;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

/**
 * 设计一个登录请求消息和登录响应消息
 *
 * @author llhuang10
 * @date 2021/10/21 19:19
 */
@Slf4j
public class MessageCodec extends ByteToMessageCodec<Message> {

    @Override
    protected void encode(ChannelHandlerContext ctx, Message msg, ByteBuf out) throws Exception {
        // 1. 4字节的魔数
        out.writeBytes(new byte[]{1, 2, 3, 4});
        // 2. 1字节的版本
        out.writeByte(1);
        // 3. 1字节的序列化方式 JDK 0, JSON 1
        out.writeByte(1);
        // 4. 1字节的指令类型
        out.writeByte(msg.getMessageType());
        // 5. 4个字节
        out.writeInt(msg.getSequenceId());
        // 无意义, 对齐填空
        out.writeByte(0xff);
        // 6.将内容转换为JSON格式
        String jsonString = JSONObject.toJSONString(msg);
        byte[] bytes = jsonString.getBytes();
        // 7.长度
        out.writeInt(bytes.length);
        // 8.写入内容
        out.writeBytes(bytes);
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        int magicNum = in.readInt();
        byte version = in.readByte();
        byte serializerType = in.readByte();
        byte messageType = in.readByte();
        int sequenceId = in.readInt();
        in.readByte();  // 读取填充位
        int length = in.readInt();

        // 根据内容长度去读取内容
        byte[] bytes = new byte[length];
        in.readBytes(bytes, 0, length);

        String jsonStr = new String(bytes);

        Message message = (Message) JSONObject.parseObject(jsonStr, Message.getMessageClass(messageType));
        log.debug("{}, {}, {}, {}, {}, {}", magicNum, version, serializerType, messageType, sequenceId, length);
        log.debug("{}", message);
        out.add(message);
    }
}
